<?php
/*********************************************
  CPG Dragonfly™ CMS
  ********************************************
  Copyright © 2004 - 2007 by CPG-Nuke Dev Team
  http://dragonflycms.org

  Dragonfly is released under the terms and conditions
  of the GNU GPL version 2 or any later version

  $Source$
  $Revision$
  $Author$
  $Date$
**********************************************/
if (!defined('CPG_NUKE')) { exit; }
if (!defined('E_DEPRECATED')) { define('E_DEPRECATED', E_WARNING); }
if (!defined('E_USER_DEPRECATED')) { define('E_USER_DEPRECATED', E_USER_WARNING); }

class cpg_debugger implements DFService {

	public $error_level;
	public $log_level;
	# later in the code degub level will be dropped as per admin preferences

	private $active = false;
	private $logfile;
	private $report;
	private $old_handler;
	private $old_display_level;
	private $old_error_logging;
	private $old_error_log;

	// E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING and some E_STRICT
	// error levels will be handled as per the error_reporting settings.
	private $errortype = array (
		//E_ERROR           => 'PHP Error',               #     1
			E_WARNING         => 'PHP Warning',             #     2
		//E_PARSE           => 'PHP Parse Error',         #     4
			E_NOTICE          => 'PHP Notice',              #     8
		//E_CORE_ERROR      => 'PHP Core Error',          #    16
		//E_CORE_WARNING    => 'PHP Core Warning',        #    32
		//E_COMPILE_ERROR   => 'PHP Compile Error',       #    64
		//E_COMPILE_WARNING => 'PHP Compile Warning',     #   128
			E_USER_ERROR      => 'CMS Error',               #   256
			E_USER_WARNING    => 'CMS Warning',             #   512
			E_USER_NOTICE     => 'CMS Notice',              #  1024
			E_STRICT          => 'PHP Strict Notice',       #  2048 PHP 5
			E_RECOVERABLE_ERROR => 'PHP Recoverable Error', #  4096 PHP 5.2
			E_DEPRECATED      => 'PHP Deprecated',          #  8192 PHP 5.3
			E_USER_DEPRECATED => 'CMS Deprecated',          # 16384 PHP 5.3
		//E_ALL             => 'PHP Error'                # 32767 PHP5.4, 30719 PHP 5.3, 6143 PHP 5.2, otherwise 2047
		);

	function __construct() {
		if ($this->active) return;
		$this->logfile = DF_LOG_FILE;
		$this->report = array();
		set_error_handler(array(&$this, 'error_handler'));
		set_exception_handler(array(&$this, 'exception_handler'));
		$this->error_level = E_ALL | E_STRICT;
		$this->log_level = E_ALL | E_STRICT;
		$this->active = true;
	}

	public function priority() { return 20; }
	public function runlevel() { return array(DF::BOOT_CORE, DF::BOOT_DOWN); }

	public function update() {
		global $DF;
		switch ($DF->getState()) {
			case DF::BOOT_DOWN: return $this->stop();
			default: return;
		}
		return;
	}

	public function stop() {
		if ($this->active) {
			restore_exception_handler();
			restore_error_handler();
			$this->active = false;
			return $this->report;
		}
	}

	public function error_handler($errno, $errmsg, $file, $linenum, $vars=array())
	{
		$errmsg = str_replace(BASEDIR, '', $errmsg);
		$file = str_replace(BASEDIR, '', $file);
		# save error to buffer
		if ($errno & $this->error_level) {
			$this->report[$file][] = $this->errortype[$errno]." line $linenum: ".$errmsg;
		}
		# save error to file
		if ($errno & $this->log_level) {
			$err = $this->errortype[$errno]." $file line $linenum: $errmsg";
			error_log($err, 0, $this->logfile);
		}
		if ($errno === E_USER_ERROR) {
			//error_log(print_r($vars, true), 0, $this->logfile);
			if ('HEAD' === $_SERVER['REQUEST_METHOD']) { Dragonfly_Net_Http::headersFlush(500); }
			if (!function_exists('cpg_error')) {
				exit($errmsg);
			}
			if (function_exists('is_admin') && is_admin()) {
				cpg_error($this->errortype[$errno]." $file line $linenum: ".$errmsg, 500);
			} else {
				cpg_error('', 500);
			}
		}
		return true;
	}

	public function exception_handler($e)
	{
		return $this->error_handler(E_USER_ERROR, $e->getMessage(), $e->getFile(), $e->getLine(), $e->getTrace());
	}

	public function get_report($type)
	{
		$debug = '';
		switch ($type) {

			case 'sql':
				global $db;
				if (!is_object($db)|| empty($db->querylist)) { break; }
				$debug .= '<span class="genmed"><strong>SQL Queries:</strong></span><br /><br />';
				foreach ($db->querylist as $file => $queries) {
					$debug .= '<b>'.$file.'</b><ul>';
					foreach ($queries as $q) { $debug .= "<li>line {$q['line']} (".round($q['time']*1000,1)." ms): {$q['query']}</li>"; }
					$debug .= '</ul>';
				}
			break;

			case 'php':
				$this->stop();
				if (!is_array($this->report)) { break; }
				foreach ($this->report as $file => $errors) {
					$debug .= '<b>'.$file.'</b><ul>';
					foreach ($errors as $error) { $debug .= "<li>$error</li>"; }
					$debug .= '</ul>';
				}
			break;

			default:
				return trigger_error('Function argument not valid', E_USER_WARNING);
			break;
		}
		return $debug;
	}

}

$cpgdebugger = new cpg_debugger;
